<script lang="ts">
export default {
  directives: {
    'select-loadmore': {
      mounted(el, binding) {
        el.addEventListener('scroll', function () {
          const condition = this.scrollHeight - this.scrollTop <= this.clientHeight;
          if (condition) {
            binding.value();
          }
        });
      },
      // 下拉框对象
    },
  },
};
</script>
<script setup lang="ts">
import { onMounted, reactive, watch } from 'vue';
import { lineService } from '@/api/line';
import { uniqBy, isEmpty } from 'lodash';

export interface NewBaseSelectProps {
  optionKey: string;
  optionName: string;
  optionCode: string;
  width: string; // 宽度
  defaultSelectedRow: any; // 默认选中的行
  placeholder?: string;
  url: string;
  search: any;
  optionProps: {
    name: string;
    value: string;
  };
  modelValue: any;
}

export interface NewBaseSelectState {
  selectValue: any;
  noMore: boolean;
  selectedList: any[];
  selectedRowKeys: any[];
  list: any[];
  loading: boolean;
  page: {
    pageNumber: number;
    pageSize: number;
    total: number;
  };
  modelValue: '';
}

const props = withDefaults(defineProps<NewBaseSelectProps>(), {
  width: '100%',
  defaultSelectedRow: () => { },
  url: '',
  search: () => { },
});

const emits = defineEmits(['update:modelValue', 'change']);

const state = reactive({
  selectValue: '',
  selectedList: [],
  selectedRowKeys: [],
  noMore: false,
  list: [],
  loading: false,
  page: {
    pageNumber: 1,
    pageSize: 10,
    total: 0,
  },
});
const filterValue = ref('');

defineExpose(state);
watch(
  () => props.search,
  (newVal) => {
    state.noMore = false;
    state.list = [];
    state.page.pageNumber = 1;
    loadMore();
  },
  {
    deep: true,
  },
);
onMounted(() => {
  state.selectValue = props.modelValue;
  // 加载完毕
  loadMore();
});

const filterMethod = (query: string) => {
  if (query) {
    state.list = [];
    state.page.pageNumber = 1;
    state.noMore = false;
    filterValue.value = query;
    const params = {
      [props.optionName]: query,
    };
    loadMore(params);
  } else {
    filterValue.value = '';
    state.noMore = false;
    state.page.pageNumber = 1;
    loadMore();
  }
};

const selectChange = (val, data) => {
  let item = undefined;
  if (val) {
    item = JSON.parse(JSON.stringify(state.list.find((item) => item[props.optionKey] === val)));
  }
  emits('change', val, item);
};

const loadMore = async (options = {}) => {
  if (!props.url) return;
  if (state.noMore) return;
  if (state.loading) return;
  state.loading = true;
  const option = {
    [props.optionName]: filterValue.value,
  };
  const params = {
    pageNumber: state.page.pageNumber,
    pageSize: state.page.pageSize,
    data: {
      ...props.search,
      ...option
      //...options,
    },
  };
  const res = await lineService[props.url](params);
  if (res.success) {
    let list = [];

    if (!isEmpty(props.defaultSelectedRow) && props.defaultSelectedRow[props.optionKey]) {
      const selectedItem = JSON.parse(JSON.stringify(props.defaultSelectedRow));
      if (props.optionKey !== 'powerId') {
        selectedItem[props.optionName] = selectedItem[props.optionName] + ` (${selectedItem[props.optionCode]})`;
      }
      list = uniqBy([...JSON.parse(JSON.stringify(state.list)), ...res.data.content, selectedItem], props.optionKey);
    } else {
      list = uniqBy([...JSON.parse(JSON.stringify(state.list)), ...res.data.content], props.optionKey);
    }

    state.list = list;
    state.noMore = res.data.lastPage;
    if (!res.data.lastPage) {
      state.page.pageNumber++;
    }
  }
  state.loading = false;
};
</script>

<template>
  <div>
    <el-select clearable :style="{ width: width }" filterable v-model="state.selectValue" :filter-method="filterMethod"
      :popper-append-to-body="false" @change="selectChange" :placeholder="props.placeholder || '请选择'">
      <!--      <div-->
      <!--          style="height: 250px; overflow: auto"-->
      <!--          v-infinite-scroll="loadMore"-->
      <!--          :infinite-scroll-delay="500"-->
      <!--          :infinite-scroll-distance="50"-->
      <!--          v-loading="state.loading"-->
      <!--          class="el-select-option-load"-->
      <!--      >-->
      <!--        <el-option-->
      <!--            v-for="(option, i) of state.list"-->
      <!--            :key="i"-->
      <!--            :label="option[props.optionProps.name]"-->
      <!--            :value="option[props.optionProps.value]"-->
      <!--        />-->
      <!--        <p v-if="state.noMore" style="text-align: center">没有更多了</p>-->
      <!--        <p v-if="state.loading" style="text-align: center">加载中...</p>-->
      <!--      </div>-->

      <div style="height: 250px; overflow: auto; overflow-anchor: none" v-select-loadmore="loadMore"
        class="el-select-option-load">
        <el-option v-for="(option, i) of state.list" :key="i" :label="option[props.optionProps.name]"
          :value="option[props.optionProps.value]" />
        <p v-if="state.noMore" style="text-align: center">没有更多了</p>
        <p v-if="state.loading" style="text-align: center">加载中...</p>
      </div>
    </el-select>
  </div>
</template>

<style lang="less" scoped>
.infinite-list-wrapper {
  height: 100%;
}

.el-select-option-load::-webkit-scrollbar {
  width: 5px;
}
</style>
